/**
 * HMR: hot module replacement 热模块替换/模块热替换
 * 作用：一个模块发生变化，只会重新打包这个一个模块
 * 极大提升速度
 * js不能使用HMR功能
 * html文件 默认不能使用HMR功能
 * 解决：修改entry入口，将html文件引入
 *
 *
 * */



const path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin') //js压缩
const MiniCssExtractPlugin = require('mini-css-extract-plugin') //抽离样式文件插件
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin') //css压缩

const {CleanWebpackPlugin} = require('clean-webpack-plugin') //编译之前删除旧的dist目录

module.exports = {
  //development、 production
  mode: "development",
  entry: ['./src/index.js','./public/index.html'],
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: "js/[name].[contenthash:10].js",
  },
  module: {
    rules: [

      {
        test: /\.css$/, //css编译
        use: [
          MiniCssExtractPlugin.loader,
          "css-loader",
          {
            //浏览器兼用性处理 注意：需要在package.json文件中加入
            //"browserslist": {
            //     "development": [
            //       "last 1 chrome version",
            //       "last 1 firefox version",
            //       "last 1 safari version"
            //     ],
            //     "production": [
            //       ">0.2%",
            //       "not dead",
            //       "not op_mini all"
            //     ]
            //   }
            loader: "postcss-loader",
            options: {
              postcssOptions:{
                plugins: [
                  "postcss-preset-env",
                ]
              }
            },
          }
        ]
      },

      {
        test: /\.s[ac]ss$/, //sass编译
        use: [
          MiniCssExtractPlugin.loader,
          "css-loader",
          {
            loader: "postcss-loader", //
            options: {
              postcssOptions:{
                plugins: [
                  "postcss-preset-env",
                ]
              }
            },
          },
          'sass-loader',
        ]
      },

      // { //非css|html|s[ac]ss|js资源文件
      //   exclude: /\.(css|html|s[ac]ss|js|jpg|png|gif)$/,
      //   loader: "file-loader",
      //   options: {
      //     name: '[hash:10].[ext]',
      //     outputPath: 'fonts',
      //   }
      // },
      { //图片编译
        test: /\.(png|jpg|gif)$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 8 * 1024,
              name: '[contenthash:10].[ext]',
              outputPath: 'images',
              esModule: false,
            },
          },
        ],
      },

      {
        test: /\.m?js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: "babel-loader",
          options: {  //es6及以上语法转成es5+ 但是不能对promise等高级语法编译，
                      // 需要在对应的js文件中添加 import '@babel/polyfill',缺点，解决所有兼容性，代码体积太大
                      // 按需加载 使用 core-js
            presets: [
              [
                '@babel/preset-env' ,
                {
                  //按需加载
                  useBuiltIns: 'usage',
                //  制定core-js版本
                  corejs: {
                    version: 3
                  },
                //  制定兼容性做到哪个版本浏览区
                  targets: {
                    chrome: '60',
                    firefox: '60',
                    ie: '9',
                    safari: '10',
                    edge: '17'
                  },
                },
              ]
            ],
            //开启babel缓存
            //地二次构件时，会读取之前的缓存
            cacheDirectory: true,
          }
        }
      },

      //html处理静态引用资源（如图片）
      {
        // 处理html中的img
        test: /\.html$/,
        loader:'html-loader',
        options: {
          // html-loader默认是以esModule的方式进行编译，而url-loader处理图片的方式是commonjs，所以需要修改一下html-loader的options配置，将esModule改为false
          esModule: false,
        }
      }
    ]
  },
  /*
    可以将node_modules中代码单独打包一个chunk最终输出
    多入口可将每个入口打包独立的文件
  * */
  optimization: {
    splitChunks: {
      chunks: "all"
    }
  },
  plugins: [

    new CleanWebpackPlugin(), //删除旧的dist目录

    new webpack.ProgressPlugin(), //编译时显示编译进度
    // new UglifyjsWebpackPlugin(), //js压缩
    // new OptimizeCssAssetsWebpackPlugin(), //css压缩
    //抽离样式文件
    new MiniCssExtractPlugin({
      filename: 'css/[name].[contenthash:10].css',
      linkType: "text/css",
    }),
    new HtmlWebpackPlugin({
      title: "webpack编译",
      template: "./public/index.html",
      minify: {
        //移除空格
        collapseWhitespace: true,
        //移除注释
        removeComments: true
      }
    })
  ],
  devtool: "eval-source-map",

  devServer: {
    contentBase: path.join(__dirname, 'dist'),
    compress: true, //是否压缩
    open: true,//是否自动打开浏览器
    //开启HMR功能
    hot: true,
  }
}
